﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Net;
using System.IO;
using System.Data.Objects;
using System.Text;
using System.Data.Objects.DataClasses;

namespace MediaService
{
    /// <summary>
    /// Service1 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务，请取消对下行的注释。
    // [System.Web.Script.Services.ScriptService]
    public class MediaService : System.Web.Services.WebService
    {
        public void DeleteResouceFromeAllResourcesTable(int resourceID)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var deletedResource = from resource in lifeShareMediaEntities.AllResouces
                           where resource.ResourceID == resourceID
                           select resource;
            if(deletedResource != null && deletedResource.Count() != 0)
            {
                lifeShareMediaEntities.DeleteObject(deletedResource.First());
                lifeShareMediaEntities.SaveChanges();
            }
        }

        [WebMethod]
        public String DeleteResource(int resourceID)
        {
            int tableIndex = GetResourceTableIndex(resourceID);
            DeleteResouceFromeAllResourcesTable(resourceID);
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            switch(tableIndex)
            {
                case 1:
                    {
                        var deletedResource = from resource in lifeShareMediaEntities.BookInfoes
                                              where resource.ResourceID == resourceID
                                              select resource;
                        if (deletedResource != null)
                        {
                            if(deletedResource.Count() != 0)
                            {
                                lifeShareMediaEntities.DeleteObject(deletedResource.First());
                                lifeShareMediaEntities.SaveChanges();
                                return "Delete Success";
                            }
                            else
                            {
                                return "Not exist";
                            }
                            
                        }
                        else
                        {
                            return "Error";
                        }
                    }
                case 2:
                    {
                        var deletedResource = from resource in lifeShareMediaEntities.MovieInfoes
                                              where resource.ResourceID == resourceID
                                              select resource;
                        if (deletedResource != null)
                        {
                            if (deletedResource.Count() != 0)
                            {
                                lifeShareMediaEntities.DeleteObject(deletedResource.First());
                                lifeShareMediaEntities.SaveChanges();
                                return "Delete Success";
                            }
                            else
                            {
                                return "Not exist";
                            }

                        }
                        else
                        {
                            return "Error";
                        }
                    }
                case 3:
                    {
                        var deletedResource = from resource in lifeShareMediaEntities.MusicInfoes
                                              where resource.ResourceID == resourceID
                                              select resource;
                        if (deletedResource != null)
                        {
                            if (deletedResource.Count() != 0)
                            {
                                lifeShareMediaEntities.DeleteObject(deletedResource.First());
                                lifeShareMediaEntities.SaveChanges();
                                return "Delete Success";
                            }
                            else
                            {
                                return "Not exist";
                            }

                        }
                        else
                        {
                            return "Error";
                        }
                    }
                default:
                    {
                        return "Not exitst";
                    }
            }
            
        }


        public int AddResourceToAllResoucesTable(int tableIndex)
        {
            //Table Index:
            //1:book 
            //2:movie
            //3:music
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            int newResourceID;
            if (lifeShareMediaEntities.AllResouces.Count() == 0)
            {
                newResourceID = 1;
            }
            else
            {
                newResourceID = lifeShareMediaEntities.AllResouces.Max(AllResouces => AllResouces.ResourceID) + 1;
            }
            AllResouce newResource = new AllResouce();
            newResource.ResourceID = newResourceID;
            newResource.TableIndex = tableIndex;
            lifeShareMediaEntities.AddToAllResouces(newResource);
            lifeShareMediaEntities.SaveChanges();
            return newResourceID;
        }


        [WebMethod]
        public String AddBook(String isbn)
        {
            string doubanBookURL = "http://api.douban.com/book/subject/isbn/";
            string resultURL = doubanBookURL + isbn;
            HttpWebRequest myRequest = null;
            HttpWebResponse myHttpResponse = null;
            myRequest = (HttpWebRequest)WebRequest.Create(resultURL);
            try
            {
                myHttpResponse = (HttpWebResponse)myRequest.GetResponse();
            }
            catch (System.Net.WebException ex)
            {
                return "Invalid isbn";
            }
            
            StreamReader reader = new StreamReader(myHttpResponse.GetResponseStream());
            string resultXMLString = reader.ReadToEnd();
            reader.Close();
            myHttpResponse.Close();

            //分析xml，然后把信息插入数据库
            try
            {
                XmlDocument resultXML = new XmlDocument();
                resultXML.LoadXml(resultXMLString);
                XmlNamespaceManager nsMgr = new XmlNamespaceManager(resultXML.NameTable);
                nsMgr.AddNamespace("db", "http://www.w3.org/2005/Atom");
                XmlElement root = resultXML.DocumentElement;
                XmlNodeList nodes = root.SelectNodes("/db:entry", nsMgr);

                LifeShareMediaEntities lifeShareContext = new LifeShareMediaEntities();
                BookInfo newBook = new BookInfo();
                foreach (XmlNode nodeData in nodes)
                {
                    foreach (XmlNode childnode in nodeData.ChildNodes)
                    {
                        string str = childnode.Name;
                        switch (str)
                        {
                            case "id":
                                newBook.OriginalDoubanID = childnode.InnerText;
                                break;
                            case "title":
                                newBook.title = childnode.InnerText;
                                break;
                            case "link":
                                if (childnode.Attributes[1].Value == "image")
                                {
                                    newBook.imageURL = childnode.Attributes[0].Value;
                                }
                                break;
                            case "summary":
                                newBook.summary = childnode.InnerText;
                                break;
                            case "gd:rating":
                                {
                                    foreach (XmlAttribute attr in childnode.Attributes)
                                    {
                                        switch (attr.Name)
                                        {
                                            case "average":
                                                newBook.ratingAverage = double.Parse(attr.Value);
                                                break;
                                            case "max":
                                                newBook.ratingMax = double.Parse(attr.Value);
                                                break;
                                            case "min":
                                                newBook.ratingMin = double.Parse(attr.Value);
                                                break;
                                            case "numRaters":
                                                newBook.numRaters = int.Parse(attr.Value);
                                                break;
                                        }
                                    }
                                    break;
                                }
                            case "db:attribute":
                                {
                                    switch (childnode.Attributes[0].Value)
                                    {
                                        case "isbn10":
                                            newBook.isbn10 = childnode.InnerText;
                                            break;
                                        case "isbn13":
                                            newBook.isbn13 = childnode.InnerText;
                                            break;
                                        case "pages":
                                            newBook.pages = int.Parse(childnode.InnerText);
                                            break;
                                        case "author":
                                            newBook.author = childnode.InnerText;
                                            break;
                                        case "price":
                                            newBook.price = childnode.InnerText;
                                            break;
                                        case "publisher":
                                            newBook.publisher = childnode.InnerText;
                                            break;
                                        case "pubdate":
                                            newBook.pubdate = childnode.InnerText;
                                            break;
                                        case "author-intro":
                                            newBook.authorIntro = childnode.InnerText;
                                            break;
                                    }
                                    break;
                                }
                        }
                    }
                }
                
                int currentResourceID=0;
                try
                {
                    currentResourceID = AddResourceToAllResoucesTable(1);
                    newBook.ResourceID = currentResourceID;
                    lifeShareContext.AddToBookInfoes(newBook);
                    lifeShareContext.SaveChanges();
                }
                catch (System.Data.UpdateException ex)
                {
                    DeleteResouceFromeAllResourcesTable(currentResourceID);
                    return "Already exist";
                }
                String successString = "Success, ID:";
                successString += currentResourceID;
                return successString;
            }
            catch (System.Exception ex)
            {
                //return ex.ToString();
                return ex.ToString();
            }
        }

        [WebMethod]
        public String AddMovie(String imdb)
        {
            string doubanBookURL = "http://api.douban.com/movie/subject/imdb/";
            string resultURL = doubanBookURL + imdb;
            HttpWebRequest myRequest = null;
            HttpWebResponse myHttpResponse = null;
            myRequest = (HttpWebRequest)WebRequest.Create(resultURL);
            try
            {
                myHttpResponse = (HttpWebResponse)myRequest.GetResponse();
            }
            catch (System.Net.WebException ex)
            {
                return "Invalid imdb";
            }

            StreamReader reader = new StreamReader(myHttpResponse.GetResponseStream());
            string resultXMLString = reader.ReadToEnd();
            reader.Close();
            myHttpResponse.Close();

            //分析xml，然后把信息插入数据库
            try
            {
                XmlDocument resultXML = new XmlDocument();
                resultXML.LoadXml(resultXMLString);
                XmlNamespaceManager nsMgr = new XmlNamespaceManager(resultXML.NameTable);
                nsMgr.AddNamespace("db", "http://www.w3.org/2005/Atom");
                XmlElement root = resultXML.DocumentElement;
                XmlNodeList nodes = root.SelectNodes("/db:entry", nsMgr);

                LifeShareMediaEntities lifeShareContext = new LifeShareMediaEntities();
                MovieInfo newMovie = new MovieInfo();
                foreach (XmlNode nodeData in nodes)
                {
                    foreach (XmlNode childnode in nodeData.ChildNodes)
                    {
                        string str = childnode.Name;
                        switch (str)
                        {
                            case "id":
                                newMovie.OriginalDoubanID = childnode.InnerText;
                                break;
                            case "title":
                                newMovie.title = childnode.InnerText;
                                break;
                            case "author":
                                {
                                    if(childnode.FirstChild.Name=="name")
                                    {
                                        newMovie.author = childnode.FirstChild.InnerText;
                                    }
                                    break;
                                }
                            case "link":
                                if (childnode.Attributes[1].Value == "image")
                                {
                                    newMovie.imageURL = childnode.Attributes[0].Value;
                                }
                                break;
                            case "summary":
                                newMovie.summary = childnode.InnerText;
                                break;
                            case "gd:rating":
                                {
                                    foreach (XmlAttribute attr in childnode.Attributes)
                                    {
                                        switch (attr.Name)
                                        {
                                            case "average":
                                                newMovie.ratingAverage = double.Parse(attr.Value);
                                                break;
                                            case "max":
                                                newMovie.ratingMax = double.Parse(attr.Value);
                                                break;
                                            case "min":
                                                newMovie.ratingMin = double.Parse(attr.Value);
                                                break;
                                            case "numRaters":
                                                newMovie.numRaters = int.Parse(attr.Value);
                                                break;
                                        }
                                    }
                                    break;
                                }
                            case "db:attribute":
                                {
                                    switch (childnode.Attributes[0].Value)
                                    {
                                        case "year":
                                            newMovie.year = int.Parse(childnode.InnerText);
                                            break;
                                        case "movie_duration":
                                            newMovie.movieDuration = childnode.InnerText;
                                            break;
                                        case "director":
                                            newMovie.director = childnode.InnerText;
                                            break;
                                    }
                                    break;
                                }
                        }
                    }
                }

                int currentResourceID = 0;
                try
                {
                    currentResourceID = AddResourceToAllResoucesTable(2);
                    newMovie.ResourceID = currentResourceID;
                    lifeShareContext.AddToMovieInfoes(newMovie);
                    lifeShareContext.SaveChanges();
                }
                catch (System.Data.UpdateException ex)
                {
                    DeleteResouceFromeAllResourcesTable(currentResourceID);
                    return "Already exist";
                }
                String successString = "Success, ID:";
                successString += currentResourceID;
                return successString;
            }
            catch (System.Exception ex)
            {
                //return ex.ToString();
                return ex.ToString();
            }
        }

        [WebMethod]
        public String AddMusic(String subjectID)
        {
            string doubanBookURL = "http://api.douban.com/music/subject/";
            string resultURL = doubanBookURL + subjectID;
            HttpWebRequest myRequest = null;
            HttpWebResponse myHttpResponse = null;
            myRequest = (HttpWebRequest)WebRequest.Create(resultURL);
            try
            {
                myHttpResponse = (HttpWebResponse)myRequest.GetResponse();
            }
            catch (System.Net.WebException ex)
            {
                return "Invalid imdb";
            }

            StreamReader reader = new StreamReader(myHttpResponse.GetResponseStream());
            string resultXMLString = reader.ReadToEnd();
            reader.Close();
            myHttpResponse.Close();

            //分析xml，然后把信息插入数据库
            try
            {
                XmlDocument resultXML = new XmlDocument();
                resultXML.LoadXml(resultXMLString);
                XmlNamespaceManager nsMgr = new XmlNamespaceManager(resultXML.NameTable);
                nsMgr.AddNamespace("db", "http://www.w3.org/2005/Atom");
                XmlElement root = resultXML.DocumentElement;
                XmlNodeList nodes = root.SelectNodes("/db:entry", nsMgr);

                LifeShareMediaEntities lifeShareContext = new LifeShareMediaEntities();
                MusicInfo newMusic = new MusicInfo();
                foreach (XmlNode nodeData in nodes)
                {
                    foreach (XmlNode childnode in nodeData.ChildNodes)
                    {
                        string str = childnode.Name;
                        switch (str)
                        {
                            case "id":
                                newMusic.OriginalDoubanID = childnode.InnerText;
                                break;
                            case "title":
                                newMusic.title = childnode.InnerText;
                                break;
                            case "author":
                                {
                                    if (childnode.FirstChild.Name == "name")
                                    {
                                        newMusic.author = childnode.FirstChild.InnerText;
                                    }
                                    break;
                                }
                            case "link":
                                if (childnode.Attributes[1].Value == "image")
                                {
                                    newMusic.imageURL = childnode.Attributes[0].Value;
                                }
                                break;
                            case "summary":
                                newMusic.summary = childnode.InnerText;
                                break;
                            case "gd:rating":
                                {
                                    foreach (XmlAttribute attr in childnode.Attributes)
                                    {
                                        switch (attr.Name)
                                        {
                                            case "average":
                                                newMusic.ratingAverage = double.Parse(attr.Value);
                                                break;
                                            case "max":
                                                newMusic.ratingMax = double.Parse(attr.Value);
                                                break;
                                            case "min":
                                                newMusic.ratingMin = double.Parse(attr.Value);
                                                break;
                                            case "numRaters":
                                                newMusic.numRaters = int.Parse(attr.Value);
                                                break;
                                        }
                                    }
                                    break;
                                }
                            case "db:attribute":
                                {
                                    switch (childnode.Attributes[0].Value)
                                    {
                                        case "discs":
                                            newMusic.discs = int.Parse(childnode.InnerText);
                                            break;
                                        case "version":
                                            newMusic.version = childnode.InnerText;
                                            break;
                                        case "ean":
                                            newMusic.ean = childnode.InnerText;
                                            break;
                                        case "tracks":
                                            newMusic.tracks = childnode.InnerText;
                                            break;
                                        case "pubdate":
                                            newMusic.pubdate = childnode.InnerText;
                                            break;
                                        case "singer":
                                            newMusic.singer = childnode.InnerText;
                                            break;
                                        case "publisher":
                                            newMusic.publisher = childnode.InnerText;
                                            break;
                                        case "radio_url":
                                            newMusic.radioURL = childnode.InnerText;
                                            break;
                                    }
                                    break;
                                }
                        }
                    }
                }

                int currentResourceID = 0;
                try
                {
                    currentResourceID = AddResourceToAllResoucesTable(3);
                    newMusic.ResourceID = currentResourceID;
                    lifeShareContext.AddToMusicInfoes(newMusic);
                    lifeShareContext.SaveChanges();
                }
                catch (System.Data.UpdateException ex)
                {
                    DeleteResouceFromeAllResourcesTable(currentResourceID);
                    return "Already exist";
                }

                String successString = "Success, ID:";
                successString += currentResourceID;
                return successString;
            }
            catch (System.Exception ex)
            {
                //return ex.ToString();
                return ex.ToString();
            }
        }

        [WebMethod]
        public BookInfo GetBookInfo(int resourceID)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var selectedResource = from resource in lifeShareMediaEntities.BookInfoes
                                   where resource.ResourceID == resourceID
                                   select resource;
            if (selectedResource == null || selectedResource.Count() == 0)
            {
                return null;
            }
            else
            {
                return selectedResource.First();
            }
        }

        [WebMethod]
        public List<BookInfo> GetAllBookInfoes()
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var resources = from resource in lifeShareMediaEntities.BookInfoes
                            select resource;

            List<BookInfo> allInfoes = new List<BookInfo>();
            foreach (var resource in resources)
            {
                allInfoes.Add(resource);
            }
            return allInfoes;
        }

        [WebMethod]
        public MovieInfo GetMovieInfo(int resourceID)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var selectedResource = from resource in lifeShareMediaEntities.MovieInfoes
                                   where resource.ResourceID == resourceID
                                   select resource;
            if (selectedResource == null || selectedResource.Count() == 0)
            {
                return null;
            }
            else
            {
                return selectedResource.First();
            }
        }

        [WebMethod]
        public List<MovieInfo> GetAllMovieInfoes()
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var resources = from resource in lifeShareMediaEntities.MovieInfoes
                        select resource;

            List<MovieInfo> allInfoes = new List<MovieInfo>();
            foreach (var resource in resources)
            {
                allInfoes.Add(resource);
            }
            return allInfoes;
        }

        [WebMethod]
        public MusicInfo GetMusicInfo(int resourceID)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var selectedResource = from resource in lifeShareMediaEntities.MusicInfoes
                                   where resource.ResourceID == resourceID
                                   select resource;
            if (selectedResource == null || selectedResource.Count() == 0)
            {
                return null;
            }
            else
            {
                return selectedResource.First();
            }
        }

        [WebMethod]
        public List<MusicInfo> GetAllMusicInfoes()
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var resources = from resource in lifeShareMediaEntities.MusicInfoes
                            select resource;

            List<MusicInfo> allInfoes = new List<MusicInfo>();
            foreach (var resource in resources)
            {
                allInfoes.Add(resource);
            }
            return allInfoes;
        }

        [WebMethod]
        public int GetResourceTableIndex(int resourceID)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var selectedResource = from resource in lifeShareMediaEntities.AllResouces
                                   where resource.ResourceID == resourceID
                                   select resource;
            if (selectedResource == null || selectedResource.Count() == 0)
            {
                return 0;
            }
            else
            {
                return selectedResource.First().TableIndex; 
            }
        }

        [WebMethod]
        public EntityObject GetResourceDetail(int resourceID)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var selectedResource = from resource in lifeShareMediaEntities.AllResouces
                                  where resource.ResourceID == resourceID
                                  select resource;
            if (selectedResource == null || selectedResource.Count()==0)
            {
                return null;
            }
            else
            {
                int tableIndex = selectedResource.First().TableIndex;
                switch(tableIndex)
                {
                    case 1:
                        {
                            var resourceDetail = from resource in lifeShareMediaEntities.BookInfoes
                                                 where resource.ResourceID == resourceID
                                                 select resource;
                            return resourceDetail.First();
                        }
                    case 2:
                        {
                            var resourceDetail = from resource in lifeShareMediaEntities.MovieInfoes
                                                 where resource.ResourceID == resourceID
                                                 select resource;
                            return resourceDetail.First();
                        }
                    case 3:
                        {
                            var resourceDetail = from resource in lifeShareMediaEntities.MusicInfoes
                                                 where resource.ResourceID == resourceID
                                                 select resource;
                            return resourceDetail.First();
                        }
                }
                return null;
            }
        }

        [WebMethod]
        public int AddComment(int userID, int resourceID, String comment)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            int newCommentID;
            if (lifeShareMediaEntities.Comments.Count() == 0)
            {
                newCommentID = 1;
            }
            else
            {
                newCommentID = lifeShareMediaEntities.Comments.Max(Comments => Comments.CommentID) + 1;
            }
            Comment newComment= new Comment();
            newComment.ResourceID = resourceID;
            newComment.CommentContent = comment;
            newComment.CommentID = newCommentID;
            newComment.CommentTime = DateTime.Now.Date + DateTime.Now.TimeOfDay;
            newComment.UserID = userID;
            lifeShareMediaEntities.AddToComments(newComment);
            lifeShareMediaEntities.SaveChanges();
            return newCommentID;
        }

        [WebMethod]
        public String DeleteComment(int commentID)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var deletedComment = from comment in lifeShareMediaEntities.Comments
                                  where comment.CommentID == commentID
                                  select comment;
            if (deletedComment != null)
            {
                if (deletedComment.Count() != 0)
                {
                    lifeShareMediaEntities.DeleteObject(deletedComment.First());
                    lifeShareMediaEntities.SaveChanges();
                    return "Delete Success";
                }
                else
                {
                    return "Not exist";
                }

            }
            else
            {
                return "Error";
            }
        }

        [WebMethod]
        public List<Comment> GetCommentList(int resourceID)
        {
            LifeShareMediaEntities lifeShareMediaEntities = new LifeShareMediaEntities();
            var comments = from comment in lifeShareMediaEntities.Comments
                           where comment.ResourceID == resourceID
                            select comment;

            List<Comment> allComments = new List<Comment>();
            foreach (var comment in comments)
            {
                allComments.Add(comment);
            }
            return allComments;
        }

    }
}